package com.tianquan.miracle.beans;

import com.tianquan.miracle.core.ClassLoad;
import com.tianquan.miracle.util.MiracleUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @Author: tianquan
 * @CreateTime: 2024-09-28  22:24
 * @Description: 实现了ClassLoad接口的类，用于扫描指定包下的所有类并加载
 */
public class ScannerClassLoad implements ClassLoad {

    /**
     * 扫描指定包名下的所有类，并将它们加载到 classNames 列表中
     *
     * @param packageName 要扫描的包的名称，例如"com.example.package"
     * @return 包含所加载类的列表
     */
    @Override
    public List<Class<?>> loadClass(String packageName) {
        // 存储找到的类
        List<Class<?>> classNames = new ArrayList<>();
        try {
            // 将包名转换为路径名
            String packagePath = packageName.replace('.', '/');
            // 获取包对应的资源路径
            Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources(packagePath);
            while (resources.hasMoreElements()) {
                URL resource = resources.nextElement();
                File directory = new File(resource.getFile());
                if (directory.exists()) {
                    // 在目录中查找类
                    findClassesInDirectory(directory, packageName, classNames);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            // 打印异常信息
            e.printStackTrace();
        }
        return classNames;
    }

    /**
     * 递归地在指定目录中查找所有的类，并将它们的类对象添加到 classNames 列表中
     *
     * @param directory   包含类文件的目录
     * @param packageName 目录对应的包名
     * @param classNames  存储找到的类的列表
     * @throws ClassNotFoundException 如果类加载失败
     */
    private static void findClassesInDirectory(File directory, String packageName, List<Class<?>> classNames) throws ClassNotFoundException {
        File[] files = directory.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                // 递归处理子目录
                findClassesInDirectory(file, packageName + "." + file.getName(), classNames);
            } else if (file.getName().endsWith(".class")) {
                // 构建类名并加载类
                String className = packageName + "." + file.getName().substring(0, file.getName().length() - 6);
                classNames.add(MiracleUtils.getClassLoader().loadClass(className));
            }
        }
    }

}




